<template>
  <div>
    <div v-if="isEnterGame===false">
      <!--    <h5 class="firstLine">Lichess账户名: {{lichessUserName}}</h5>-->
      <!--    各种筛选条件-->
      <el-select v-model="selectType" placeholder="对局类型" size="mini" filterable style="width: 100px" class="firstLine"
                 clearable>
        <el-option
            v-for="item in selectTypeList"
            :key="item.value"
            :label="item.label"
            :value="item.value">
        </el-option>
      </el-select>
      <el-select v-model="selectTime" placeholder="对局限时" size="mini" filterable style="width: 100px" class="firstLine"
                 clearable>
        <el-option
            v-for="item in selectTimeList"
            :key="item.value"
            :label="item.label"
            :value="item.value">
        </el-option>
      </el-select>
      <p class="firstLine" style="margin-left: 10px">排序条件:</p>
      <el-select v-model="orderByKey" placeholder="排序" size="mini" filterable style="width: 100px" class="firstLine">
        <el-option
            v-for="item in orderBySelect"
            :key="item.value"
            :label="item.label"
            :value="item.value">
        </el-option>
      </el-select>
      <el-radio v-model="order" label="desc" class="firstLine">降序</el-radio>
      <el-radio v-model="order" label="asc" class="firstLine">升序</el-radio>

      <el-date-picker
          v-model="selectDate"
          align="right"
          type="date"
          placeholder="~至今"
          :picker-options="pickerOptions"
          size="mini"
          style="width:130px"
          clearable
      >
      </el-date-picker>
      <el-select v-model="selectResult" placeholder="结果" size="mini" style="width: 90px" class="firstLine"
                 clearable>
        <el-option
            v-for="item in resultSelect"
            :key="item.value"
            :label="item.label"
            :value="item.value">
        </el-option>
      </el-select>
      <el-select v-model="selectAnalyze" placeholder="分析" size="mini" style="width: 90px" class="firstLine"
                 clearable>
        <el-option
            v-for="item in analyzeSelect"
            :key="item.value"
            :label="item.label"
            :value="item.value">
        </el-option>
      </el-select>
      <el-button size="mini" type="primary" @click="searchByCond" style="margin-left: 10px">查询</el-button>
      <el-button size="mini" :type="!isAnalyzeAll ? 'danger' : 'warning'" :disabled="analyzeDisabled" @click="analyzeAll" style="margin-left: 10px">{{!isAnalyzeAll ? '自动分析' : '结束分析'}}</el-button>
      <!--    导入按钮-->
      <div style="float: right;margin-right:5px">
        <el-tooltip class="item" effect="dark" content="每1000局棋约需要5分钟，此后只会同步最新的数据，会跳过特殊规则下的棋局" placement="top">
          <el-button class="firstLine" size="mini" type="success" @click="getDataFromLichess"
                     v-loading.fullscreen.lock="fullscreenLoading">同步数据
          </el-button>
        </el-tooltip>
        <el-tooltip class="item" effect="dark"
                    content="导入其他平台的Pgn或者从Lichess下载Pgn自行导入数据，每1000局棋约需要2分钟" placement="top">
          <el-upload
              ref="upload"
              class="firstLine"
              accept=".pgn"
              action="#"
              :file-list="fileList"
              :auto-upload="false"
              :show-file-list="false"
              :on-change="importPgn"
          >
            <el-button type="primary" size="mini">导入Pgn</el-button>
          </el-upload>
        </el-tooltip>
      </div>

      <el-table :data="gameData" stripe border :height="630" style="margin-top: 10px">
        <el-table-column
            prop="event" :show-overflow-tooltip="true"
            label="赛事"
            width="100">
        </el-table-column>
        <el-table-column
            prop="type" :show-overflow-tooltip="true"
            label="类型"
            width="80">
        </el-table-column>
        <el-table-column
            prop="white" :show-overflow-tooltip="true"
            label="白方"
            width="120">
        </el-table-column>
        <el-table-column
            prop="whiteElo" :show-overflow-tooltip="true"
            label="白方Elo"
            width="80">
        </el-table-column>
        <el-table-column :show-overflow-tooltip="true"
                         prop="black"
                         label="黑方"
                         width="120">
        </el-table-column>
        <el-table-column
            prop="blackElo" :show-overflow-tooltip="true"
            label="黑方Elo"
            width="80">
        </el-table-column>
        <el-table-column
            prop="time" :show-overflow-tooltip="true"
            label="时间规则"
            width="80">
        </el-table-column>

        <el-table-column :show-overflow-tooltip="true"
                         prop="opening"
                         label="开局"
                         width="100">
        </el-table-column>
        <el-table-column
            prop="result"
            label="结果"
            width="80">
        </el-table-column>
        <el-table-column
            prop="analyzed"
            label="分析"
            width="50">
        </el-table-column>
        <el-table-column :show-overflow-tooltip="true"
                         prop="gameDate"
                         label="对局时间"
                         width="170">
        </el-table-column>
        <el-table-column
            fixed="right"
            label="操作"
        >
          <template slot-scope="scope">
            <el-button type="primary" size="mini" @click="learnGame(scope.row)">查看</el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
          style="float: right; margin: 5px 20px 5px 5px;"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="currentPage"
          :page-sizes="[20, 50, 100]"
          :page-size="20"
          layout="total, sizes, prev, pager, next, jumper"
          :total="gameCount">
      </el-pagination>
    </div>
    <div v-if="isEnterGame===true">
      <Board :game-info="singleGame"></Board>
    </div>
  </div>

</template>

<script>

import {existValue, invoke, sleep} from "@/lib/utils";
import Sqlite from "@/lib/sqlite";
import Chessmate from "@/lib/chessmate";
import {getMyGames} from "@/lib/reptile";
import fs from "fs";
import {clipboard} from "electron";
import chessmate from "@/lib/chessmate";
import path from "path";
import Database from "@/lib/database";
import moment from "moment";
import Board from "@/components/user/Board.vue";
import emitvue from "@/lib/emitvue";
import _ from "lodash";

export default {
  name: "example",
  data() {
    return {
      dbFolderPath: '',
      lichessUserName: '',
      fileList: [],
      fullscreenLoading: false,
      gameData: [],
      gameCount: 0,
      // 页码和大小
      currentPage: 1,
      currentSize: 20,
      selectType: '',
      selectTime: '',
      selectTypeList: [],
      selectTimeList: [],
      order: 'desc',
      orderByKey: 'gameDate',
      orderBySelect: [
        {label: '对局时间', value: 'gameDate'},
        {label: '白方ELO', value: 'whiteElo'},
        {label: '黑方ELO', value: 'blackElo'},
      ],
      resultSelect: [
        {label: '我赢了', value: 'win'},
        {label: '我输了', value: 'lose'},
        {label: '平局', value: 'draw'},
      ],
      selectResult: '',
      analyzeSelect: [
        {label: '已分析', value: 1},
        {label: '未分析', value: 0},
      ],
      selectAnalyze: '',
      selectDate: '',
      // 时间的限制
      pickerOptions: {
        disabledDate(time) {
          return time.getTime() > Date.now();
        },
        shortcuts: [
          {
            text: '今年',
            onClick(picker) {
              picker.$emit('pick', moment().startOf('years').valueOf());
            }
          },
          {
            text: '去年',
            onClick(picker) {
              picker.$emit('pick', moment().startOf('years').add(-1, 'years').valueOf());
            }
          },
          {
            text: '本月',
            onClick(picker) {
              picker.$emit('pick', moment().startOf('months').valueOf());
            }
          },
          {
            text: '上个月',
            onClick(picker) {

              picker.$emit('pick', moment().startOf('months').add(-1, 'months').valueOf());
            }
          },
          {
            text: '本周',
            onClick(picker) {
              picker.$emit('pick', moment().startOf('isoWeeks').valueOf());
            }
          },
        ]
      },
      isEnterGame: false,
      singleGame: {},
      isAnalyzeAll: false,
      analyzeDisabled: false,
      fastAnalyze: false,
    }
  },
  methods: {
    async getDataFromLichess() {
      if (!this.lichessUserName) return this.$notify({duration: 1000, title: '通知', message: "请先去设置你的Lichess账户名", type: 'warning'})
      this.fullscreenLoading = true
      // 先判断数据库是否有数据 有数据拿最新的一局棋之后的棋局
      const last = await Database.getLastUserGame()
      let since = null
      if (last && last.length) since = last[0].gameDate
      const {status, data} = await getMyGames(this.lichessUserName, since)

      if (status === 404) return this.$notify({duration: 1000, title: '通知', message: "Lichess不存在该用户", type: 'error'})
      if (existValue(status) && status !== 404) return this.$notify({duration: 1000, title: '通知', message: "系统错误，请联系开发者", type: 'error'})
      const {gameCount, jumpCount} = await chessmate.parsePgnStore(data)
      this.fullscreenLoading = false
      await sleep(500)
      if (gameCount) {
        this.$notify({duration: 1000, title: '通知', message: `成功导入${gameCount}个对局，跳过了${jumpCount}个特殊对局`, type: 'success'})
      } else {
        this.$notify({duration: 1000, title: '通知', message: `暂无新的对局`, type: 'warning'})
      }
      await this.getGameData()
    },
    async importPgn(file) {
      const filePath = file?.raw?.path
      const data = fs.readFileSync(filePath, 'utf-8')
      this.fullscreenLoading = true
      const {gameCount, jumpCount} = await chessmate.parsePgnStore(data)
      this.$refs.upload.clearFiles()
      this.fullscreenLoading = false
      await sleep(500)
      if (gameCount) {
        this.$notify({duration: 1000, title: '通知', message: `成功导入${gameCount}个对局，跳过了${jumpCount}个特殊对局`, type: 'success'})
      } else {
        this.$notify({duration: 1000, title: '通知', message: `暂无新的对局`, type: 'warning'})
      }
      await this.getGameData()
    },
    async getSetting() {
      this.appPath = await invoke('getCurrentPath', null)
      let config = await invoke('get', {name: 'setting', type: 'database'})
      this.lichessUserName = config.lichessUserName
      this.pluginPath = config.pluginPath
      this.dbFolderPath = config.dbFolderPath
      this.fastAnalyze = config.rapidAnalyzeGame || false
      const chessConfig = {
        path: config.enginePath,
        analyzeSpeed: config.analyzeSpeed,
        blunderThreshold: config.blunderThreshold,
        mistakeThreshold: config.mistakeThreshold,
      }
      this.exportFilePath = config.exportFilePath || './'
      await Chessmate.init(chessConfig)
    },
    // 检查user.db是否存在于用户目录 不存在则复制
    async checkUserDb() {
      const userCachePath = await invoke('getUserDataPath', null)
      const userDbPath = path.join(userCachePath, './chessmate/user.db')
      const dbDir = path.join(userCachePath, './chessmate')
      const backUpDBPath = path.join(this.dbFolderPath, './user.db')
      if (!fs.existsSync(backUpDBPath)) {
        return this.$notify({duration: 1000, title: '通知', message: "备份数据未找到，请联系开发者", type: 'error'})
      }
      // 理论上这个文件夹只要程序打开就一定存在
      if (!fs.existsSync(dbDir)) {
        fs.mkdirSync(dbDir)
      }
      if (!fs.existsSync(userDbPath)) {
        fs.copyFileSync(backUpDBPath, userDbPath)
        this.$notify({duration: 1000, title: '通知', message: `已成功初始化用户数据`, type: 'success'})
      }
      await Sqlite.connectUser(userDbPath)
      await this.getGameData()
      await this.getSelectDistinct()
    },
    // 按条件查询的按钮
    async searchByCond() {
      // 先把分页重置
      this.currentSize = 20
      this.currentPage = 1
      await this.getGameDataByCond()
    },
    // 学习开局
    learnGame(data) {
      emitvue.$emit('clearUserGame', null)
      this.singleGame = data
      this.isEnterGame = true
    },
    async handleCurrentChange(data) {
      if (this.currentPage === data) return
      this.currentPage = data
      await this.getGameDataByCond(false)
    },
    async handleSizeChange(data) {
      if (this.currentSize === data) return
      this.currentSize = data
      await this.getGameDataByCond(false)
    },
    async getGameData(cond = null) {
      const res = await Database.getGameByPage(this.currentSize, (this.currentPage - 1) * this.currentSize, cond)
      this.gameData = res.data
      this.gameCount = res.count[0]?.count || 0
      for (const item of this.gameData) {
        item.gameDate = moment(Number(item.gameDate)).format('YYYY-MM-DD HH:mm:ss')
        item.analyzed = item.analyzed === 0 ? '否' : '是'
      }
    },
    // 按条件查询
    async getGameDataByCond(message=true) {
      if (this.selectDate) {
        this.selectDate = moment(this.selectDate).valueOf()
      }
      const cond = {
        time: this.selectTime,
        type: this.selectType,
        order: this.order,
        orderByKey: this.orderByKey,
        gameDate: this.selectDate,
        userName: this.lichessUserName,
        result: this.selectResult,
        analyze: this.selectAnalyze,
      }
      await this.getGameData(cond)
      if (message) this.$notify({duration: 1000, title: '通知', message: `已成功获取数据`, type: 'success'})

    },
    async getSelectDistinct() {
      this.selectTimeList = []
      this.selectTypeList = []
      const distinct = await Database.getTypeAndTimeFromGame()
      const {time, type} = distinct
      // 将对局时间优化排序
      for (const item of time) {
        const rule = item.time.split("+")
        const fTime = Number(rule[0]) || 10000000
        this.selectTimeList.push({label: item.time, value: item.time, time: fTime})
      }
      for (const item of type) {
        this.selectTypeList.push({label: item.type, value: item.type})
      }
      this.selectTimeList = _.orderBy(this.selectTimeList, ['time'], ['asc'])
    },
    // 分析全部
    async analyzeAll() {
      // 先看看万一没有要分析的咋办
      const data = await Database.getNotAnalyzedGame()
      if (!data.length) return this.$notify({duration: 1000, title: '通知', message: '未找到需要分析的棋局', type: 'warning'})
      this.isAnalyzeAll = !this.isAnalyzeAll
      if (!this.isAnalyzeAll) {
        const count = Chessmate.exitAnalyze()
        if (count) this.$notify({duration: 1000, title: '通知', message: `已经分析了约${count}个对局，请等待最后一局棋分析完成再开始自动分析`, type: 'success'})
        this.analyzeDisabled = true
      } else {
        emitvue.$emit('beginAnalyze')
        this.$notify({duration: 1000, title: '通知', message: '正在以设置的分析精度进行自动分析', type: 'warning'})
        await Chessmate.analyzeAll(this.fastAnalyze)
      }
    },
  },
  async mounted() {
    await this.getSetting()
    await this.checkUserDb()
    emitvue.$on('exitUserGame', async ()=>{
      this.isEnterGame = false
      await this.getGameDataByCond(false)
    })
    emitvue.$on("analyzeStop", async ()=>{
      console.log("接收到分析完成的通知")
      if (this.analyzeDisabled === false) return
      this.analyzeDisabled = false
      emitvue.$emit('exitAnalyze')
    })
    emitvue.$on("analyzeRealStop", async () => {
      console.log("接收全部分析完成的通知")
      this.analyzeDisabled = false
      this.isAnalyzeAll = false
      emitvue.$emit('exitAnalyze')
    })
  },
  watch: {
    async analyzeDisabled() {
      if (this.analyzeDisabled === false) {
        this.$message({message: '分析已全部完成', type: 'success', duration: 1000})
        await this.getGameDataByCond(false)
      }
    }
  },
  components: {
    Board
  },
}
</script>


<style scoped>
.firstLine {
  display: inline-block;
  margin: 5px;
}
</style>